package cn.coin.ox.util;

import cn.coin.ox.test.ETFTestMain;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.Keys;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthTransaction;
import org.web3j.protocol.core.methods.response.Transaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class ETHUtil {

    private static Logger log = LoggerFactory.getLogger(ETHUtil.class);

    /**
     * 获取eth的Credentials
     * @param walleFilePath
     * @param passWord
     * @return
     * @throws Exception
     */
    public static Credentials getCredentials(String walleFilePath, String passWord) throws Exception{
        Credentials credentials = WalletUtils.loadCredentials(passWord, walleFilePath);
        return credentials;
    }



    /********加载钱包文件**********/
    public static Map<String, Object> loadWallet(Credentials credentials) throws IOException, CipherException {
        String address = credentials.getAddress();
        BigInteger publicKey = credentials.getEcKeyPair().getPublicKey();
        BigInteger privateKey = credentials.getEcKeyPair().getPrivateKey();
        System.out.println(privateKey);
        String prikey = Numeric.toHexStringWithPrefixZeroPadded(privateKey, Keys.PRIVATE_KEY_LENGTH_IN_HEX);
        System.out.println(prikey);
//        publicKey = new BigInteger(publicKey.toString(), 16);
        System.out.println("第二步: 加载钱包信息（如下）:");
        System.out.println("-钱包地址:" + address);
        System.out.println("-私钥:" + prikey);
        System.out.println("-公钥:" + publicKey);
//        log.info("address="+address);
//        log.info("public key="+publicKey);
//        log.info("private key="+privateKey);
        Map<String, Object> map = new HashMap<>();
        map.put("address", address);
        map.put("privateKey", privateKey);
        map.put("publicKey", publicKey);
        return map;
    }

    /*******连接以太坊客户端**************/
    public static Web3j createETHclient(String token) throws IOException {
        //连接方式1：使用infura 提供的客户端
        // TODO: 2018/4/10 token更改为自己的
        Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/"+token));
        //连接方式2：使用本地客户端
//        Web3j web3j = Web3j.build(new HttpService("127.0.0.1:7545"));
        //测试是否连接成功
        String web3ClientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
        log.info("version=" + web3ClientVersion);
        return web3j;
    }

    /***********查询指定地址的余额***********/
    public static String getBlanceOf(Web3j web3j, String address) throws IOException {
        if (web3j == null){
            return "";
        }
//        String address = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";//等待查询余额的地址
        //第二个参数：区块的参数，建议选最新区块
        EthGetBalance balance = web3j.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();
        //格式转化 wei-ether
        String blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString().concat(" ether");
        log.info(blanceETH);
        return blanceETH;
    }

    /****************交易*****************/
    public static void transto(Web3j web3j, Credentials credentials, String addressTo, BigDecimal amount) throws Exception {
        if (web3j == null) return;
        if (credentials == null) return;
        //开始发送0.01 =eth到指定地址
//        String addressTo = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";
        BigDecimal bg = new BigDecimal("10000"); // 0.01
        TransactionReceipt send = Transfer.sendFunds(web3j, credentials, addressTo, amount, Convert.Unit.SZABO).sendAsync().get();
        log.info("Transaction complete:");
        log.info("trans hash=" + send.getTransactionHash());
        log.info("from :" + send.getFrom());
        log.info("to:" + send.getTo());
        log.info("gas used=" + send.getGasUsed());
        log.info("status: " + send.getStatus());
    }

    public static Transaction ethGetTransactionByHash(Web3j web3j, String hash) throws Exception{
        EthTransaction ethTransaction = web3j.ethGetTransactionByHash(hash).sendAsync().get();
        Transaction send = ethTransaction.getTransaction().get();
        log.info("Transaction complete:");
        log.info("from :" + send.getFrom());
        log.info("to:" + send.getTo());
        log.info("gas used=" + send.getGas());
        log.info("Gas Price Raw: " + send.getGasPriceRaw());
        return send;
    }


}
